/* This file is part of GSMC.
 * 
 * GSMC is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GSMC is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with GSMC.  If not, see <http://www.gnu.org/licenses/>.
 */

package net.hpxn.gsmc.action.util;

import java.io.*;

import net.hpxn.gsmc.action.BaseAction;

public class ActionClassLoader extends ClassLoader {

	private String root;
	
	public ActionClassLoader() { }

	public ActionClassLoader( String rootDir ) {
		if ( rootDir == null ) {
			throw new IllegalArgumentException( "Null root directory" );
		}
		root = rootDir;
	}

	@SuppressWarnings("unchecked")
	protected Class<BaseAction> loadClass( String name, boolean resolve )
					throws ClassNotFoundException {
		if ( root == null ) {
			throw new IllegalArgumentException( "Null root directory." );
		}
		
		Class<BaseAction> c = (Class<BaseAction>) findLoadedClass( name );

		if ( c == null ) {
			try {
				c = (Class<BaseAction>) findSystemClass( name );
			} catch ( Exception e ) {
			}
		}

		if ( c == null ) {
			String filename =
				name.replace( '.', File.separatorChar ) + ".class";

			try {
				byte data[] = loadClassData( filename );
				c =
					(Class<BaseAction>) defineClass( name, data, 0, data.length );
				if ( c == null ) {
					throw new ClassNotFoundException( name );
				}
			} catch ( IOException e ) {
				throw new ClassNotFoundException( "Error reading file: "
						+ filename );
			}
		}

		if ( resolve )
			resolveClass( c );
		return c;
	}

	private byte[] loadClassData( String filename ) throws IOException {

		File f = new File( root, filename );

		int size = (int) f.length();

		byte buff[] = new byte[size];

		FileInputStream fis = new FileInputStream( f );
		DataInputStream dis = new DataInputStream( fis );

		dis.readFully( buff );
		dis.close();

		return buff;
	}
}
